package com.cty.util.util;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;

/**
 * 线程工具类
 *
 * @author : cty
 * @since 2023/11/19
 */

@Slf4j
public class ThreadUtils<T> {

    /**
     * 线程执行结果
     */
    private final List<CompletableFuture<T>> futureList;

    /**
     * 线程池
     */
    private final CustomThreadPoolTaskExecutor customThreadPoolTaskExecutor = SpringUtil.getBean(CustomThreadPoolTaskExecutor.class);

    public ThreadUtils() {
        futureList = new ArrayList<>();
    }


    /**
     * 异步处理任务 且 等待返回结果
     *
     * @param supplier 任务执行器
     * @return 执行结果
     */
    public T asyncSubmit(Supplier<T> supplier) {
        try {
            CompletableFuture<T> completable = CompletableFuture.supplyAsync(supplier, customThreadPoolTaskExecutor).handle((res, e) -> {
                if (e != null) {
                    log.error(":::::> fork/join 异步执行 异常：", e);
                }
                return res;
            });
            futureList.add(completable);
            return completable.get();
        } catch (InterruptedException e) {
            log.error(":::::> fork/join 异步执行中断，异常信息：", e);
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            log.error(":::::> fork/join 异步执行异常，异常信息：", e);
        }
        return null;
    }

    /**
     * 异步处理任务 且 无需等待返回
     *
     * @param supplier 任务执行器
     */
    public void asyncExecute(Supplier<T> supplier) {
        try {
            CompletableFuture<T> completable = CompletableFuture.supplyAsync(supplier, customThreadPoolTaskExecutor).handle((res, e) -> {
                if (e != null) {
                    log.error(":::::> fork/join 异步执行，异常信息：", e);
                }
                return res;
            });
            futureList.add(completable);
        } catch (Exception e) {
            log.error(":::::> fork/join 异步执行，异常信息：", e);
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 等待所有异步任务执行结束
     */
    public void allOfJoin() {
        CompletableFuture[] futures = new CompletableFuture[futureList.size()];
        CompletableFuture.allOf(futureList.toArray(futures)).join();
    }

    /**
     * 获取所有异步任务的结果列表
     * 注：适用于同一任务循环执行多次获取返回结果的场景
     * @return 结果列表
     */
    public List<T> getAllOfJoinResult() {
        List<T> resultList = new ArrayList<>();
        try {
            if (!futureList.isEmpty()) {
                for (CompletableFuture<T> future : futureList) {
                    T result = future.get();
                    if (null != result) {
                        resultList.add(result);
                    }
                }
            }
        } catch (Exception e) {
            Thread.currentThread().interrupt();
            log.error(":::::> fork/join 异步执行，异常信息：", e);
        }
        return resultList;
    }

}
